package myzzyl.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import myzzyl.constants.ErrorConstants;
import myzzyl.domain.dto.SysRoleDto;
import myzzyl.domain.pojo.SysRole;
import myzzyl.domain.pojo.SysRoleResource;
import myzzyl.domain.pojo.SysUserRole;
import myzzyl.domain.vo.SysRoleVo;
import myzzyl.exception.BusinessException;
import myzzyl.mapper.SysRoleResourceMapper;
import myzzyl.response.PageResponse;
import myzzyl.service.SysResourceService;
import myzzyl.service.SysRoleResourceService;
import myzzyl.service.SysRoleService;
import myzzyl.mapper.SysRoleMapper;
import myzzyl.service.SysUserRoleService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
* @author 33249
* @description 针对表【sys_role(角色表)】的数据库操作Service实现
* @createDate 2025-08-20 14:33:28
*/
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole>
    implements SysRoleService {


    @Autowired
    private SysRoleResourceService sysRoleResourceService;

    @Autowired
    private SysUserRoleService sysUserRoleService;


    /**
     * 获取角色列表数据
     * @param pageNum 页码
     * @param pageSize 页数
     * @param sysRoleDto 角色表单请求封装类
     * @return 返回值
     */
    @Override
    public PageResponse<SysRole> pageQuery(Integer pageNum, Integer pageSize, SysRoleDto sysRoleDto) {
        // 创建分页对象
        Page<SysRole> page = new Page<>(pageNum, pageSize);

        // 添加排序字段
        page.addOrder(OrderItem.asc("sort_no"), OrderItem.desc("create_time"));

        // 分页查询
        Page<SysRole> sysRolePage = lambdaQuery()
                .like(StrUtil.isNotBlank(sysRoleDto.getRoleName()),
                        SysRole::getRoleName, sysRoleDto.getRoleName())
                .page(page);

        // 构造基本分页响应对象返回
        return new PageResponse<>(sysRolePage.getPages(), sysRolePage.getTotal(), sysRolePage.getRecords());
    }


    /**
     * 获取所有角色数据
     * @return 返回值
     */
    @Override
    public List<SysRole> getAll() {
        return list();
    }

    /**
     * 获取角色绑定的资源
     * @param roleId 角色id
     * @return 返回值
     */
    @Override
    public List<String> getCheckedResources(Long roleId) {
        // 判断角色是否存在
        SysRole sysRole = getById(roleId);
        if(sysRole == null) {
            throw new BusinessException(ErrorConstants.ROLE_IS_NOT_EXIST);
        }

        return sysRoleResourceService.selectResourceNosByRoleId(roleId);
    }

    /**
     * 获取角色详情数据
     * @param id 角色id
     * @return 返回值
     */
    @Override
    public SysRole getInfo(Long id) {
        SysRole sysRole = getById(id);
        if(sysRole == null) {
            throw new BusinessException(ErrorConstants.ROLE_IS_NOT_EXIST);
        }

        return sysRole;
    }


    /**
     * 新增角色
     * @param sysRoleDto 角色表单请求封装类
     * @return 返回值
     */
    @Override
    public boolean add(SysRoleDto sysRoleDto) {
        // 判断角色名称是否为空
        if (StrUtil.isBlank(sysRoleDto.getRoleName())) {
            throw new BusinessException(ErrorConstants.ROLE_NAME_IS_NULL);
        }

        // 查询角色是否已经存在
        if (lambdaQuery().eq(SysRole::getRoleName, sysRoleDto.getRoleName()).exists()) {
            throw new BusinessException(ErrorConstants.ROLE_IS_ALREADY_EXIST);
        }

        // 新增角色
        SysRole sysRole = new SysRole();
        BeanUtils.copyProperties(sysRoleDto, sysRole);
        sysRole.setDataState("0");

        return save(sysRole);
    }


    /**
     * 编辑角色
     * @param sysRoleDto 角色表单请求封装类
     * @return 返回值
     */
    @Override
    @Transactional
    public boolean edit(SysRoleDto sysRoleDto) {
        // 判断选中的资源编号是否为空
        if (sysRoleDto.getCheckedResourceNos() == null) {
            // 为空，说明是编辑角色本身信息
            // 判断角色名称是否为空
            if (StrUtil.isBlank(sysRoleDto.getRoleName())) {
                throw new BusinessException(ErrorConstants.ROLE_NAME_IS_NULL);
            }

            // 查询角色是否已经存在（除去自己）
            if (lambdaQuery()
                    .eq(SysRole::getRoleName, sysRoleDto.getRoleName())
                    .ne(SysRole::getId, sysRoleDto.getId())
                    .exists()) {
                throw new BusinessException(ErrorConstants.ROLE_IS_ALREADY_EXIST);
            }

            // 判断字段是否禁用状态
            if (sysRoleDto.getDataState().equals("1")) {
                // 查询角色是否已经绑定了用户
                if (sysUserRoleService.lambdaQuery()
                                  .eq(SysUserRole::getRoleId, sysRoleDto.getId())
                                  .exists()) {
                    throw new BusinessException(ErrorConstants.ROLE_HAS_USER);
                }
            }

            // 更新角色
            return lambdaUpdate()
                    .set(SysRole::getRoleName, sysRoleDto.getRoleName())
                    .set(SysRole::getDataState, sysRoleDto.getDataState())
                    .set(SysRole::getDataScope, sysRoleDto.getDataScope())
                    .eq(SysRole::getId, sysRoleDto.getId())
                    .update();
        }else {
            // 不为空，说明是角色绑定的资源编辑
            // 先删除角色原先绑定的资源
            sysRoleResourceService.removeResourceByRoleId(sysRoleDto.getId());

            // 判断资源是否为空
            if (CollectionUtil.isEmpty(sysRoleDto.getCheckedResourceNos())) {
                return true;
            }

            // 不为空的情况下，再构造角色-资源存储集合
            List<SysRoleResource> sysRoleResources = sysRoleDto.getCheckedResourceNos()
                    .stream()
                    .map(resourceNo -> {
                        SysRoleResource sysRoleResource = new SysRoleResource();
                        sysRoleResource.setRoleId(sysRoleDto.getId());
                        sysRoleResource.setResourceNo(resourceNo);

                        return sysRoleResource;
                    }).toList();

            // 批量新增
            return sysRoleResourceService.saveBatch(sysRoleResources);
        }
    }


    /**
     * 删除角色
     * @param id 角色id
     * @return 返回值
     */
    @Override
    @Transactional
    public boolean remove(Long id) {
        // 查询角色是否存在
        SysRole sysRole = getById(id);
        if(sysRole == null) {
            throw new BusinessException(ErrorConstants.ROLE_IS_NOT_EXIST);
        }

        // 判断角色的状态是否为启用
        if (sysRole.getDataState().equals("0")) {
            throw new BusinessException(ErrorConstants.ROLE_IS_ACTIVE);
        }

        // 先删除角色
        int rows = baseMapper.deleteById(id);
        if (rows > 0) {
            // 再删除角色绑定的资源
            sysRoleResourceService.removeResourceByRoleId(id);
            return true;
        }
        return false;
    }


}
